package com.atguigu.tingshu.user.service.impl;
import java.util.*;
import java.util.stream.Collectors;

import cn.binarywang.wx.miniapp.api.WxMaService;
import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.common.constant.KafkaConstant;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.service.KafkaService;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.dto.UserInfoDto;
import com.atguigu.tingshu.model.user.UserPaidAlbum;
import com.atguigu.tingshu.model.user.UserPaidTrack;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.atguigu.tingshu.user.context.UpdateUserPaidRecordStrategyContext;
import com.atguigu.tingshu.user.mapper.UserPaidAlbumMapper;
import com.atguigu.tingshu.user.mapper.UserPaidTrackMapper;
import com.atguigu.tingshu.vo.user.UserInfoVo;


import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.model.user.UserInfo;
import com.atguigu.tingshu.user.mapper.UserInfoMapper;
import com.atguigu.tingshu.user.service.UserInfoService;
import com.atguigu.tingshu.vo.user.UserPaidRecordVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

	@Autowired
	private UserInfoMapper userInfoMapper;

	@Autowired
	private WxMaService wxMaService;

	@Autowired
	private RedisTemplate<String,String> redisTemplate;

	@Autowired
	private KafkaService kafkaService;

	@Autowired
	private UserPaidAlbumMapper userPaidAlbumMapper;

	@Autowired
	private UserPaidTrackMapper userPaidTrackMapper;

	@Override
	public Map<String, String> wxLogin(String code) {

		if(StringUtils.isEmpty(code)) {
			throw new GuiguException(ResultCodeEnum.ARGUMENT_VALID_ERROR);

		}

		try {
			WxMaJscode2SessionResult sessionResult = wxMaService.getUserService().getSessionInfo(code);

			String openid = sessionResult.getOpenid();

			LambdaQueryWrapper<UserInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
			lambdaQueryWrapper.eq(UserInfo::getWxOpenId,openid);
			UserInfo userInfo = userInfoMapper.selectOne(lambdaQueryWrapper);

			if (userInfo == null){
				userInfo = new UserInfo();
				userInfo.setWxOpenId(openid);
				userInfo.setNickname("听听"+ System.currentTimeMillis());
				userInfo.setAvatarUrl("https://www.duitang.com/blog/?id=1416225742");
				userInfo.setStatus("1");
				userInfoMapper.insert(userInfo);

				kafkaService.sendMsg(KafkaConstant.QUEUE_USER_REGISTER,String.valueOf(userInfo.getId()));


			}

			String token = UUID.randomUUID().toString().replaceAll("-","");

			String redisKey = RedisConstant.USER_LOGIN_KEY_PREFIX +token;

			redisTemplate.opsForValue().set(redisKey, JSON.toJSONString(userInfo),RedisConstant.USER_LOGIN_KEY_TIMEOUT);

			//  将这两个数据存储到map中并返回
			HashMap<String, String> map = new HashMap<>();
			map.put("token",token);

			//  返回数据
			return map;

		} catch (WxErrorException e) {
			e.printStackTrace();
			throw new GuiguException( ResultCodeEnum.LOGIN_ERROR);
		}


	}

	@Override
	public UserInfoVo getUserInfoVoByUserId(Long userId) {
		UserInfo userInfo = this.getById(userId);				//	获取到用户信息对象
		UserInfoVo userInfoVo = new UserInfoVo();				//	创建UserInfoVo 对象
		BeanUtils.copyProperties(userInfo,userInfoVo);			//	属性拷贝
		return userInfoVo;
	}

	@Override
	public void updateUser(UserInfoDto userInfoDto) {
		Long userId = AuthContextHolder.getUserId();
		UserInfo userInfo = userInfoMapper.selectById(userId);
		userInfo.setNickname(userInfoDto.getNickname());
		userInfo.setAvatarUrl(userInfoDto.getAvatarUrl());
		userInfoMapper.updateById(userInfo);

	}

	@Override
	public Map<Long, Long> userIsPaidTrack(Long userId, Long albumId, List<Long> trackIdList) {
		//	根据UserId,albumId 获取到用户付款专辑对象
		LambdaQueryWrapper<UserPaidAlbum> userPaidAlbumLambdaQueryWrapper = new LambdaQueryWrapper<>();
		userPaidAlbumLambdaQueryWrapper.eq(UserPaidAlbum::getUserId,userId).eq(UserPaidAlbum::getAlbumId,albumId);
		UserPaidAlbum userPaidAlbum = userPaidAlbumMapper.selectOne(userPaidAlbumLambdaQueryWrapper);

		//	创建一个map集合对象封装结果数据
		HashMap<Long, Long> map = new HashMap<>();

		//	判断
		if (null != userPaidAlbum){  //	如果查询到对应的专辑购买记录，则默认将声音Id的购买情况设置为1

			trackIdList.forEach(trackId->{
				map.put(trackId,1L);
			});

			return map;

		} else {

			//	根据用户Id 与专辑Id 查询用户购买声音记录
			LambdaQueryWrapper<UserPaidTrack> userPaidTrackLambdaQueryWrapper = new LambdaQueryWrapper<>();
			userPaidTrackLambdaQueryWrapper.eq(UserPaidTrack::getUserId,userId).in(UserPaidTrack::getTrackId,trackIdList);
			List<UserPaidTrack> userPaidTrackList = userPaidTrackMapper.selectList(userPaidTrackLambdaQueryWrapper);

			//	获取到用户购买声音Id 集合
			List<Long> userPaidTrackIdList = userPaidTrackList.stream().map(UserPaidTrack::getTrackId).collect(Collectors.toList());

			// 遍历声音id的集合，判断当前遍历的声音是否购买过
			trackIdList.forEach(trackId ->{
				if (userPaidTrackIdList.contains(trackId)){		//	用户已购买声音
					map.put(trackId,1L);
				}else {
					map.put(trackId,0L);
				}
			});

			return map;
		}
	}

	@Override
	public Boolean isPaidAlbum(Long albumId, Long userId) {
		LambdaQueryWrapper<UserPaidAlbum> lambdaQueryWrapper = new LambdaQueryWrapper<>() ;
		lambdaQueryWrapper.eq(UserPaidAlbum::getUserId , userId) ;
		lambdaQueryWrapper.eq(UserPaidAlbum::getAlbumId , albumId) ;
		UserPaidAlbum userPaidAlbum = userPaidAlbumMapper.selectOne(lambdaQueryWrapper);
		return userPaidAlbum != null;
	}

	@Override
	public List<Long> findUserPaidTrackList(Long albumId) {
		// 获取当前登录用户的id
		Long userId = AuthContextHolder.getUserId();

		// 构建查询条件对象
		LambdaQueryWrapper<UserPaidTrack> lambdaQueryWrapper = new LambdaQueryWrapper<>() ;
		lambdaQueryWrapper.eq(UserPaidTrack::getAlbumId , albumId) ;
		lambdaQueryWrapper.eq(UserPaidTrack::getUserId , userId) ;
		List<UserPaidTrack> userPaidTrackList = userPaidTrackMapper.selectList(lambdaQueryWrapper);
		List<Long> trackIds = userPaidTrackList.stream().map(userPaidTrack -> userPaidTrack.getTrackId()).collect(Collectors.toList());

		return trackIds;
	}

	@Override
	public void updateUserPaidRecord(UserPaidRecordVo userPaidRecordVo) {
		UpdateUserPaidRecordStrategyContext.getByItemType(userPaidRecordVo.getItemType()).updateUserPaidRecord(userPaidRecordVo);

	}

}

